// Copyright (c) 2023 Presto Labs Pte. Ltd.
// Author: daniel

#pragma once

#include <cstdint>
#include <unordered_map>

#include "coin2/base/math/time_moving_window.h"

namespace coin2::exchange::base::order {

class RecentActiveSymbol {
  class Handler {
   public:
    explicit Handler(RecentActiveSymbol* recent_active_symbol)
        : recent_active_symbol_(recent_active_symbol) {}

    template <typename P1, typename P2>
    void OnPushed(P1&& p1, P2&& p2) {
      recent_active_symbol_->AddEvent(p1, p2);
    }
    template <typename P1, typename P2>
    void OnPopped(P1&& p1, P2&& p2) {
      recent_active_symbol_->DelEvent(p1, p2);
    }
    void OnClear() {}

   private:
    RecentActiveSymbol* recent_active_symbol_;
  };

 public:
  explicit RecentActiveSymbol(int64_t window_size);
  void AddActiveEvent(int64_t ts, const std::string& symbol);
  bool HasActiveEvent(int64_t ts, const std::string& symbol);

 protected:
  void AddEvent(int64_t ts, const std::string& symbol);
  void DelEvent(int64_t ts, const std::string& symbol);

 private:
  using MovingWindow = coin2::base::math::TimeMovingWindow<std::string, Handler>;
  MovingWindow active_symbol_window_;
  std::unordered_map<std::string, int64_t> active_symbol_map_;
};

}  // namespace coin2::exchange::base::order
